﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TaskBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            using (TB.Scope())
            {
                new Program().Do();
            }
            System.Threading.Thread.Sleep(2000);
        }

        private void Do()
        {
            var thrdIn = TB.Input<string>();
            var t = new Thread(() =>
                {
                    for (int i = 0; i < 10; i++)
                    {
                        thrdIn.Write("Hello");
                        Thread.Sleep(1000);
                        thrdIn.Write(" World\n");
                        Thread.Sleep(1000);
                    }
                });
            t.Start();
            TB.Act(Console.Write, thrdIn);
        }

        private string Modify(string input)
        {
            return input + " World";
        }

        private IEnumerable<string> InputA()
        {
            yield return "Hello";
        }

        private IEnumerable<string> InputB()
        {
            yield return "World";
        }

        private void Output(string[] inputs)
        {
            Console.WriteLine("{0} {1}", inputs[0], inputs[1]);
        }

        // pure producer
        static IEnumerable<int> g1()
        {
            yield return 10;
            yield return 11;
            yield return 12;
        }

        static IEnumerable<int> g2()
        {
            yield return 25;
            yield return 26;
            yield return 27;
        }

        static IEnumerable<int[]> g3()
        {
            yield return new[] { 25, 10, 5, 19 };
            yield return new[] { 26, 11, 6, 20 };
            yield return new[] { 27, 12, 7, 21 };
        }

        // consumer-producer
        static string f1(int x)
        {
            return string.Format("x = {0}", x);
        }

        static string f2(string s)
        {
            return string.Format("f2: {0}", s);
        }

        static string f3(string s)
        {
            return string.Format("f3: {0}", s);
        }

        static int[] f4(Tuple<int, int> t)
        {
            return new int[] { t.Item1, t.Item2 };
        }

        // pure consumer
        static void a1(string s)
        {
            Console.WriteLine("a1: {0}", s);
        }

        static void a2(string s)
        {
            Console.WriteLine("a2: {0}", s);
        }

        static void a3(int[] x)
        {
            Console.WriteLine("x = {0}, {1}", x[0], x[1]);
        }

        static void a4(int i)
        {
            Console.WriteLine("a4: {0}", i);
        }
    }
}
